
#include "clib_hash_fnv32.h"


#define CLIB_FNV32_PRIME          (16777619)
#define CLIB_FNV32_OFFSET_BASIS   (2166136261)

clib_uint32_t clib_hash_fnv32_1(clib_uint8_t const *data, size_t size, clib_uint32_t seed) {
    clib_check_if_true_return_value(data == NULL, 0);
    clib_check_if_true_return_value(size == 0, 0);
    clib_uint32_t value = CLIB_FNV32_OFFSET_BASIS;
    if (seed) {
        value = (value * CLIB_FNV32_PRIME) ^ seed;
    }
    while (size) {
        value *= CLIB_FNV32_PRIME;
        value ^= (clib_uint32_t) *data++;
        size--;
    }
    return value;
}

clib_uint32_t clib_hash_fnv32_1_from_string(char const *string, clib_uint32_t seed) {
    clib_check_if_true_return_value(string == NULL, 0);
    return clib_hash_fnv32_1((clib_uint8_t const *) string, strlen(string) + 1, seed);
}


clib_uint32_t clib_hash_fnv32_1a(clib_uint8_t const *data, size_t size, clib_uint32_t seed) {
    clib_check_if_true_return_value(data == NULL, 0);
    clib_check_if_true_return_value(size == 0, 0);
    clib_uint32_t value = CLIB_FNV32_OFFSET_BASIS;
    if (seed) {
        value = (value * CLIB_FNV32_PRIME) ^ seed;
    }

    while (size) {
        value ^= (clib_uint32_t) *data++;
        value *= CLIB_FNV32_PRIME;
        size--;
    }
    return value;
}


clib_uint32_t clib_hash_fnv32_1a_from_string(char const *string, clib_uint32_t seed) {
    clib_check_if_true_return_value(string == NULL, 0);
    return clib_hash_fnv32_1a((clib_uint8_t const *) string, strlen(string) + 1, seed);
}